package cn.iocoder.yudao.module.iot.service.mqtt;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.module.iot.core.messagebus.core.IotMessageBus;
import cn.iocoder.yudao.module.iot.dal.dataobject.scene.IotSceneActionDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
import cn.iocoder.yudao.module.iot.dal.mysql.device.IotDeviceMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import jakarta.annotation.Resource;

/**
 * IoT MQTT 消息发送服务实现类
 *
 * @author 芋道源码
 */
@Service
@Slf4j
public class IotMqttServiceImpl implements IotMqttService {

    @Resource
    private IotMessageBus messageBus;
    
    @Resource
    private IotDeviceMapper deviceMapper;

    @Override
    public void sendDeviceControlMessage(IotSceneActionDO action) {
        if (action == null || action.getDeviceId() == null) {
            log.warn("[sendDeviceControlMessage][设备控制指令参数无效，action: {}]", action);
            return;
        }

        try {
            // 查询设备信息
            IotDeviceDO device = deviceMapper.selectById(action.getDeviceId());
            if (device == null) {
                log.error("[sendDeviceControlMessage][设备不存在，设备ID: {}]", action.getDeviceId());
                return;
            }
            
            // 构建消息内容
            DeviceControlMessage message = DeviceControlMessage.builder()
                    .deviceId(action.getDeviceId())
                    .actionType(action.getActionType())
                    .actionValue(action.getActionValue())
                    .attr(action.getAttr())
                    .value(action.getValue())
                    .timestamp(System.currentTimeMillis())
                    .build();

            // 发送消息到消息总线，让订阅者处理
            messageBus.post("/sys/device/control", message);
            
            log.info("[sendDeviceControlMessage][发送设备控制指令成功，设备ID: {}, 设备名: {}, 产品Key: {}, 动作: {}, 主题: /sys/device/control]", 
                    action.getDeviceId(), device.getDeviceName(), device.getProductKey(), action.getActionType());
                    
        } catch (Exception e) {
            log.error("[sendDeviceControlMessage][发送设备控制指令失败，设备ID: {}, 动作: {}]", 
                    action.getDeviceId(), action.getActionType(), e);
        }
    }

    @Override
    public void sendSceneUpdateMessage(Long sceneId) {
        if (sceneId == null) {
            log.warn("[sendSceneUpdateMessage][场景ID为空]");
            return;
        }

        try {
            String topic = "iot/scene/update";
            SceneUpdateMessage message = SceneUpdateMessage.builder()
                    .sceneId(sceneId)
                    .timestamp(System.currentTimeMillis())
                    .build();

            messageBus.post(topic, message);
            
            log.info("[sendSceneUpdateMessage][发送场景更新消息成功，场景ID: {}, 主题: {}]", sceneId, topic);
            
        } catch (Exception e) {
            log.error("[sendSceneUpdateMessage][发送场景更新消息失败，场景ID: {}]", sceneId, e);
        }
    }

    @Override
    public void sendSceneDeleteMessage(Long sceneId) {
        if (sceneId == null) {
            log.warn("[sendSceneDeleteMessage][场景ID为空]");
            return;
        }

        try {
            String topic = "iot/scene/delete";
            SceneDeleteMessage message = SceneDeleteMessage.builder()
                    .sceneId(sceneId)
                    .timestamp(System.currentTimeMillis())
                    .build();

            messageBus.post(topic, message);
            
            log.info("[sendSceneDeleteMessage][发送场景删除消息成功，场景ID: {}, 主题: {}]", sceneId, topic);
            
        } catch (Exception e) {
            log.error("[sendSceneDeleteMessage][发送场景删除消息失败，场景ID: {}]", sceneId, e);
        }
    }

    @Override
    public void sendThresholdSettingMessage(Long deviceId, String thresholdType, Double thresholdValue) {
        if (deviceId == null || thresholdType == null || thresholdValue == null) {
            log.warn("[sendThresholdSettingMessage][阈值设置参数无效，设备ID: {}, 阈值类型: {}, 阈值数值: {}]", 
                    deviceId, thresholdType, thresholdValue);
            return;
        }

        try {
            // 查询设备信息
            IotDeviceDO device = deviceMapper.selectById(deviceId);
            if (device == null) {
                log.error("[sendThresholdSettingMessage][设备不存在，设备ID: {}]", deviceId);
                return;
            }
            
            // 构建阈值设置消息
            ThresholdSettingMessage message = ThresholdSettingMessage.builder()
                    .deviceId(deviceId)
                    .thresholdType(thresholdType)
                    .thresholdValue(thresholdValue)
                    .timestamp(System.currentTimeMillis())
                    .build();

            // 发送消息到消息总线，让订阅者处理
            messageBus.post("/sys/device/threshold", message);
            
            log.info("[sendThresholdSettingMessage][发送阈值设置指令成功，设备ID: {}, 设备名: {}, 产品Key: {}, 阈值类型: {}, 阈值数值: {}, 主题: /sys/device/threshold]", 
                    deviceId, device.getDeviceName(), device.getProductKey(), thresholdType, thresholdValue);
                    
        } catch (Exception e) {
            log.error("[sendThresholdSettingMessage][发送阈值设置指令失败，设备ID: {}, 阈值类型: {}, 阈值数值: {}]", 
                    deviceId, thresholdType, thresholdValue, e);
        }
    }

    @Override
    public void sendRadarSettingMessage(Long deviceId, java.util.Map<String, Object> radarSettings) {
        if (deviceId == null || radarSettings == null || radarSettings.isEmpty()) {
            log.warn("[sendRadarSettingMessage][雷达设置参数无效，设备ID: {}, 雷达设置: {}]", 
                    deviceId, radarSettings);
            return;
        }

        try {
            // 查询设备信息
            IotDeviceDO device = deviceMapper.selectById(deviceId);
            if (device == null) {
                log.error("[sendRadarSettingMessage][设备不存在，设备ID: {}]", deviceId);
                return;
            }
            
            // 构建雷达设置消息
            RadarSettingMessage message = RadarSettingMessage.builder()
                    .deviceId(deviceId)
                    .radarSettings(radarSettings)
                    .timestamp(System.currentTimeMillis())
                    .build();

            // 发送消息到消息总线，让订阅者处理
            messageBus.post("/sys/device/radar", message);
            
            log.info("[sendRadarSettingMessage][发送雷达设置指令成功，设备ID: {}, 设备名: {}, 产品Key: {}, 雷达设置: {}, 主题: /sys/device/radar]", 
                    deviceId, device.getDeviceName(), device.getProductKey(), radarSettings);
                    
        } catch (Exception e) {
            log.error("[sendRadarSettingMessage][发送雷达设置指令失败，设备ID: {}, 雷达设置: {}]", 
                    deviceId, radarSettings, e);
        }
    }

    /**
     * 设备控制消息
     */
    public static class DeviceControlMessage {
        private Long deviceId;
        private String actionType;
        private String actionValue;
        private String attr;
        private String value;
        private Long timestamp;

        // Builder 模式
        public static Builder builder() {
            return new Builder();
        }

        public static class Builder {
            private DeviceControlMessage message = new DeviceControlMessage();

            public Builder deviceId(Long deviceId) {
                message.deviceId = deviceId;
                return this;
            }

            public Builder actionType(String actionType) {
                message.actionType = actionType;
                return this;
            }

            public Builder actionValue(String actionValue) {
                message.actionValue = actionValue;
                return this;
            }

            public Builder attr(String attr) {
                message.attr = attr;
                return this;
            }

            public Builder value(String value) {
                message.value = value;
                return this;
            }

            public Builder timestamp(Long timestamp) {
                message.timestamp = timestamp;
                return this;
            }

            public DeviceControlMessage build() {
                return message;
            }
        }

        // Getters
        public Long getDeviceId() { return deviceId; }
        public String getActionType() { return actionType; }
        public String getActionValue() { return actionValue; }
        public String getAttr() { return attr; }
        public String getValue() { return value; }
        public Long getTimestamp() { return timestamp; }
    }

    /**
     * 场景更新消息
     */
    public static class SceneUpdateMessage {
        private Long sceneId;
        private Long timestamp;

        public static Builder builder() {
            return new Builder();
        }

        public static class Builder {
            private SceneUpdateMessage message = new SceneUpdateMessage();

            public Builder sceneId(Long sceneId) {
                message.sceneId = sceneId;
                return this;
            }

            public Builder timestamp(Long timestamp) {
                message.timestamp = timestamp;
                return this;
            }

            public SceneUpdateMessage build() {
                return message;
            }
        }

        public Long getSceneId() { return sceneId; }
        public Long getTimestamp() { return timestamp; }
    }

    /**
     * 场景删除消息
     */
    public static class SceneDeleteMessage {
        private Long sceneId;
        private Long timestamp;

        public static Builder builder() {
            return new Builder();
        }

        public static class Builder {
            private SceneDeleteMessage message = new SceneDeleteMessage();

            public Builder sceneId(Long sceneId) {
                message.sceneId = sceneId;
                return this;
            }

            public Builder timestamp(Long timestamp) {
                message.timestamp = timestamp;
                return this;
            }

            public SceneDeleteMessage build() {
                return message;
            }
        }

        public Long getSceneId() { return sceneId; }
        public Long getTimestamp() { return timestamp; }
    }

    /**
     * 阈值设置消息
     */
    public static class ThresholdSettingMessage {
        private Long deviceId;
        private String thresholdType;
        private Double thresholdValue;
        private Long timestamp;

        public static Builder builder() {
            return new Builder();
        }

        public static class Builder {
            private ThresholdSettingMessage message = new ThresholdSettingMessage();

            public Builder deviceId(Long deviceId) {
                message.deviceId = deviceId;
                return this;
            }

            public Builder thresholdType(String thresholdType) {
                message.thresholdType = thresholdType;
                return this;
            }

            public Builder thresholdValue(Double thresholdValue) {
                message.thresholdValue = thresholdValue;
                return this;
            }

            public Builder timestamp(Long timestamp) {
                message.timestamp = timestamp;
                return this;
            }

            public ThresholdSettingMessage build() {
                return message;
            }
        }

        public Long getDeviceId() { return deviceId; }
        public String getThresholdType() { return thresholdType; }
        public Double getThresholdValue() { return thresholdValue; }
        public Long getTimestamp() { return timestamp; }
    }

    /**
     * 雷达设置消息
     */
    public static class RadarSettingMessage {
        private Long deviceId;
        private java.util.Map<String, Object> radarSettings;
        private Long timestamp;

        public static Builder builder() {
            return new Builder();
        }

        public static class Builder {
            private RadarSettingMessage message = new RadarSettingMessage();

            public Builder deviceId(Long deviceId) {
                message.deviceId = deviceId;
                return this;
            }

            public Builder radarSettings(java.util.Map<String, Object> radarSettings) {
                message.radarSettings = radarSettings;
                return this;
            }

            public Builder timestamp(Long timestamp) {
                message.timestamp = timestamp;
                return this;
            }

            public RadarSettingMessage build() {
                return message;
            }
        }

        public Long getDeviceId() { return deviceId; }
        public java.util.Map<String, Object> getRadarSettings() { return radarSettings; }
        public Long getTimestamp() { return timestamp; }
    }
} 